var dictModule = {};

dictModule.html =
'<h2 id="infoDictHead" onclick="if(res = prompt(\'Найти в cловаре:\', this.innerHTML), res!=null && res!=\'\') dictModule.showA(res.toLowerCase());" class="origin">dictionary</h2>'+
'<div>'+
'	<input type="button" class="dcBut" id="dictPrevBut" disabled="disabled" value="&#8666;" onclick="dictModule.showA(dictModule.dh.previous(), true)">'+
'	<input type="button" class="dcBut" id="dictNextBut" disabled="disabled" value="&#8667;" onclick="dictModule.showA(dictModule.dh.next(), true)" style="float:right" >'+
'</div>'+
'<button id="playInfoDict" onclick="dictModule.playWord( getElem(\'infoDictHead\').innerHTML );">'+
'	<div id="swPlayer" style="height:0"></div><audio id="swHtml5Player" src=""></audio>'+
'	<input type="checkbox" onclick="event.stopPropagation();" id="checkboxWordAutoPlaying" title="Word Auto Playing"/>'+
'	<span id="playSign" >&#9654;</span>'+
'	<span id="infoDictTranscription" class="transcription">[\ˈdɪkʃənrɪ]</span>'+
'</button>'+
'<div id="infoDictContent">&#9997; Здесь будут отображаться словарные статьи. Щелкните по заголовку если хотите найти произвольную статью.</div>';

dictModule.init = function( elem ){
    elem.innerHTML = this.html;
}

/** обертка в словарную ссылку */
dictModule.wrapDictLink = function(word, value){
    value = value || word;
    return '<a href="javascript:void(0)" onclick="dictModule.showA(\''+value+'\')">'+word+'</a>';
}

dictModule.playWord = function( word, isPhrase ){
    isPhrase = isPhrase || /[^\w]/.test(word); // фраза или слово
    if(isPhrase) return;// отключаем поддержку фраз

    var aSrc = !isPhrase ? 'http://www.howjsay.com/mp3/'+( word.toLowerCase() )+'.mp3'
        : encodeURIComponent('http://translate.google.com/translate_tts?tl=en&q='+ word );

    if(typeof window.Audio=='function' && !isPhrase){//swHtml5Player
        getElem('swHtml5Player').src = aSrc;
        getElem('swHtml5Player').play();
    }else{
        getElem('swPlayer').innerHTML='<object onerror="alert(\''+word+'\')" type="application/x-shockwave-flash" ' +
            'data="http://denis-or-love.narod.ru/ump3player_500x70.swf" height="0" width="0">' +
            '<param name="wmode" value="transparent">' +
            '<param name="allowScriptAccess" value="always">' +
            '<param name="movie" value="http://flv-mp3.com/i/pic/ump3player_500x70.swf">' +
            '<param name="FlashVars" value="way='+
            aSrc +
            '&swf=http://flv-mp3.com/i/pic/ump3player_500x70.swf&w=0'+
            '&h=0&autoplay=1&volume=100">'+
            '</object>';
    }
}

dictModule.initA = function(dict, word, navigation){
    if( !dict || ! dict[ word ] ) return null;

    var tr = this.getTranscription(word);
    return {word:word, a:dict[ word ].a, as:this.styleA(dict, word, true), tr: tr!=word ? tr : ''};
}

dictModule.showInitARes = function(initAResult){
    getElem('infoDictHead').innerHTML = initAResult.word;
    getElem('infoDictContent').innerHTML = initAResult.as;// article stylizated
    getElem('infoDictTranscription').innerHTML = initAResult.tr ;

    var isPhrase = /[^\w]/.test(initAResult.word); // фраза или слово
    getElem('playSign').style.display = isPhrase ?'none':'inline';
        //isPhrase ? getElem('playInfoDict').setAttribute('disabled', 'disabled' ) : getElem('playInfoDict').removeAttribute('disabled');

    dictModule.infoWinShow('infoDict');
}

dictModule.infoWinShow = function( id ){
    //jQuery('.infoContent').hide(); $('#'+id).show();
}

dictModule.showA = function(word, navigation){
    var initAResult = this.initA(window.transEngRus, word, navigation);
    if(initAResult!=null){
        // если не навигация по истории и не повтор рядом стоящих то вставляем в историю
        if(!navigation && this.dh.getCurrent()!=word && this.dh.getNext()!=word) {
            this.dh.insert(word);
        }
        var dictPrevBut = getElem('dictPrevBut'),
            dictNextBut = getElem('dictNextBut');
        if(this.dh.hasPrevious()){
            dictPrevBut.removeAttribute('disabled');
            dictPrevBut.value = '⇚'+this.dh.getPrevious();
        }else{
            dictPrevBut.setAttribute('disabled', 'disabled');
            dictPrevBut.value = '⇚';
        }

        if(this.dh.hasNext()){
            dictNextBut.removeAttribute('disabled');
            dictNextBut.value = this.dh.getNext()+'⇛';
        }else{
            dictNextBut.setAttribute('disabled', 'disabled');
            dictNextBut.value = '⇛';
        }

        this.showInitARes(initAResult);
    }

    return initAResult;
}

dictModule.styleA = function(dict, word, forHtml){
    if( !dict || ! dict[ word ] ) return '';
    forHtml = forHtml || false;
    var br = forHtml ? "<br/>" : "\n",
        tb = forHtml ? "&nbsp; " : "  ",
        tb3 = new Array(4).join(tb);

    var wB = function(s, t){ t=t||'b';return '<'+t+'>'+s+'</'+t+'>'};// wrap tag, def:BOLD
	
	return dict[ word ].a
        .replace(/(?:\s)?((^I|II|III|IV)\s)/g, // II
            br+wB('$1','h4'))//'<br />$1')        
		
		.replace(/(\n|= )([a-z '\-]+)/ig, // english phrase to pseudo-links showA()
            function(all, b, p){
                if( dObj = dictModule.dictGet(dict, p) ) { //w[i] in dict   .toLowerCase()
                    p = dictModule.wrapDictLink(p, dObj.fw);
                }
                return b+'<b class="origin">'+ p +'</b>';
            }
        )/**/
        .replace(/([^a-z\.]) ([a-z\s\-\'\.,\:!\?]+)([\s]|$)/ig, // english words to pseudo-links showA()//  ([^a-z])
            function(all, b, a, e){
                var dObj, w = a.split(/\b/ig); //console.log(w);
                for(var i=0;i<w.length;i++){
                    if( dObj = dictModule.dictGet(dict, w[i]) ) { //w[i] in dict   .toLowerCase()
                        w[i]= dictModule.wrapDictLink(w[i], dObj.fw);
                    }
                }
                return b+' <b class="origin">'+ w.join('') +'</b> '+e;//
            }
        )
        
        //replace(/;([^;]+[;\s]*а\)\s)/ig, //; some text; а)
        //';'+br+tb3+'$1').
        .replace(/([^aа-я])([aа-я]\)\s)([a-zа-я])/ig, // а) б) в)//(;|\s|\n|^)
            '$1'+br+tb3+wB('$2')+'$3')
        .replace(/(\d+\)\s)/g, // 1)
            br+tb+wB('$1'))//'<br />&nbsp; &nbsp;1)
        .replace(/(?:^|\s)(\d+\.\s)/g, // 1.
            br+wB('$1'))//'<br />$1')

		.replace(/\n/g, br)// \n
        .replace(/<br\/><br\/>/g, '<br/>')// delete vain br
}

dictModule.getTranscription = function( string ){
    if( !window.transEngRus || string==null || string.length<2) return string;

    var w = this.dictGet(window.transEngRus, string), arr;
    if ( w!=undefined && w.t!='') return w.t;

    arr = string.split(/\b/ig);
    if(arr.length<2) return string;

    for(var i=0; i<arr.length;i++){
        if(arr[i].trim().length>0)
            arr[i] = this.getTranscription( arr[i] ) ;
    }

    return arr.join('');
}

dictModule.dictGet = function(dict, word){
    var r = null, o, q='', cnt=0;
    o = dict[ word.toLowerCase() ] || dict[ firstToUpper(word) ];

    while(!o && word.length>2 && cnt<4){
        cnt++;
        q = word.substr(-1)+q;
        o = dict[ word = word.slice(0,-1) ];
    }
    if( o ){
        r = {
            // article
            a: o.a,
            //transcription
            t: o.t ? '['+(o.t+q).replace(/(\[|\])/g, '')+']' : '',
            // finded word
            fw:word
        };
    }
    return r;
}

dictModule.dictFind = function(dict, word){
    var r = null, o, cnt=0, aword;
    o =  dict[ word = firstToUpper(word) ] || dict[ word = word.toLowerCase() ];
    if(!o && /.+ie[sd]$/.test(word)){
        o = dict[aword = word.replace(/ie[sd]$/,'y')];
        if( o ) word = aword;
    }

    while(!o && word.length>2 && cnt<4){
        cnt++;
        o = dict[ word = word.slice(0,-1) ];
        if(!o){
            o = dict[ word = word +'e' ];
        }
        if(!o){
            o = dict[ word = word.slice(0,-1)+'y' ];
        }
        if(!o){
            word = word.slice(0,-1);
        }
    }
    if( o ){
        r = {
            // article
            a: o.a,
            // finded word
            fw:word
        };
    }
    return r;
};

dictModule.dictFindSmart = function(dict, word, oWord){
    oWord = oWord || word;// оригинальное слово
    var dfRes=this.dictFind(dict, word), initAResult=null;
    if(dfRes!=null){
        word = dfRes.fw;
        initAResult = this.initA(dict, word);
    }else{// отрубаем посл. букву
        if(word = myprompt(word+' is not found.\nMaybe:', word.slice(0,-1) ), word!=null && word!='')
            return this.dictFindSmart(dict, word, oWord);
        else
            return null;
    }

    return initAResult;
}

/** История навигации по словарю */
dictModule.dh = new HistoryNavigator();
function HistoryNavigator(){
    var index=-1,
        array=[];
    this.insert=function(newEl){
        array.splice(index+1,0,newEl);
        index++;
    };
    this.hasNext=function(){
        return index<array.length-1;
    };
    this.hasPrevious=function(){
        return index>0;
    };
    this.next=function(){
        if(!this.hasNext()) return null;
        return array[++index];
    };
    this.previous=function(){
        if(!this.hasPrevious()) return null;
        return array[--index];
    };
    // без перехода указателя
    this.getNext=function(){
        return this.hasNext() ? array[index+1] : null;
    };
    // без перехода указателя
    this.getPrevious=function(){
        return this.hasPrevious() ? array[index-1] : null;
    };
    this.getCurrent=function(){
        if(index<0) return null;
        return array[index];
    };
    this.getArray=function(){ return array; };
    this.getIndex=function(){ return index; };
}